// Kony

#include "AbilitySystem/Data/LevelConfig.h"
#include "Engine/DataTable.h"

TArray<FLevelConfigInfo> ULevelConfig::LoadConfigsFromDataTable(UDataTable* DataTable)
{
	TArray<FLevelConfigInfo> Configs;
	
	if (!DataTable)
	{
		UE_LOG(LogTemp, Warning, TEXT("ULevelConfig::LoadConfigsFromDataTable - DataTable is null"));
		return Configs;
	}

	// 从DataTable加载所有行数据
	TArray<FLevelConfigInfo*> AllRows;
	DataTable->GetAllRows<FLevelConfigInfo>(TEXT("LoadLevelConfig"), AllRows);

	for (FLevelConfigInfo* Row : AllRows)
	{
		if (Row)
		{
			Configs.Add(*Row);
		}
	}

	// 按MinLevel排序
	Configs.Sort([](const FLevelConfigInfo& A, const FLevelConfigInfo& B)
	{
		return A.MinLevel < B.MinLevel;
	});

	UE_LOG(LogTemp, Log, TEXT("ULevelConfig::LoadConfigsFromDataTable - Loaded %d level configs"), Configs.Num());
	return Configs;
}

int32 ULevelConfig::CalculateXPForLevel(UDataTable* DataTable, int32 Level)
{
	if (Level <= 1)
	{
		return 0;
	}

	TArray<FLevelConfigInfo> Configs = LoadConfigsFromDataTable(DataTable);
	int32 ConfigIndex = FindConfigIndexForLevel(Configs, Level);
	if (ConfigIndex == INDEX_NONE)
	{
		UE_LOG(LogTemp, Warning, TEXT("ULevelConfig::CalculateXPForLevel - No config found for level %d"), Level);
		return 0;
	}

	const FLevelConfigInfo& Config = Configs[ConfigIndex];
	int32 TotalXP = 0;

	// 计算之前境界的总经验值
	for (int32 i = 0; i < ConfigIndex; ++i)
	{
		const FLevelConfigInfo& PrevConfig = Configs[i];
		int32 LevelsInThisConfig = PrevConfig.MaxLevel - PrevConfig.MinLevel + 1;
		
		for (int32 LevelInConfig = 1; LevelInConfig <= LevelsInThisConfig; ++LevelInConfig)
		{
			int32 XPForThisLevel = FMath::RoundToInt(PrevConfig.BaseXP * FMath::Pow(PrevConfig.XPMultiplier, LevelInConfig - 1));
			TotalXP += XPForThisLevel;
		}
	}

	// 计算当前境界内的经验值
	int32 LevelInCurrentConfig = Level - Config.MinLevel + 1;
	for (int32 LevelInConfig = 1; LevelInConfig <= LevelInCurrentConfig; ++LevelInConfig)
	{
		int32 XPForThisLevel = FMath::RoundToInt(Config.BaseXP * FMath::Pow(Config.XPMultiplier, LevelInConfig - 1));
		TotalXP += XPForThisLevel;
	}

	return TotalXP;
}

int32 ULevelConfig::FindLevelForXP(UDataTable* DataTable, int32 CurrentLevel, int32 CurrentXP)
{
	if (!DataTable || CurrentXP <= 0)
	{
		return CurrentLevel;
	}

	TArray<FLevelConfigInfo> Configs = LoadConfigsFromDataTable(DataTable);
	if (Configs.Num() == 0)
	{
		return CurrentLevel;
	}

	int32 NewLevel = CurrentLevel;
	int32 RemainingXP = CurrentXP;

	// 循环检查是否可以升级
	while (RemainingXP > 0)
	{
		// 获取当前等级升级所需的经验值
		int32 XPRequiredForCurrentLevel = GetXPRequiredForCurrentLevel(DataTable, NewLevel);
		
		if (RemainingXP >= XPRequiredForCurrentLevel)
		{
			// 可以升级
			RemainingXP -= XPRequiredForCurrentLevel;
			NewLevel++;
			
			// 检查是否已达到当前修炼阶段的最高等级
			int32 ConfigIndex = FindConfigIndexForLevel(Configs, NewLevel);
			if (ConfigIndex == INDEX_NONE)
			{
				// 没有找到配置，可能需要进入下一个修炼阶段
				ConfigIndex = FindConfigIndexForLevel(Configs, NewLevel - 1);
				if (ConfigIndex != INDEX_NONE && ConfigIndex + 1 < Configs.Num())
				{
					// 进入下一个修炼阶段
					NewLevel = Configs[ConfigIndex + 1].MinLevel;
				}
				else
				{
					// 已达到最高等级，回退一级
					NewLevel--;
					break;
				}
			}
		}
		else
		{
			// 经验不足，无法升级
			break;
		}
	}

	return NewLevel;
}

FLevelConfigInfo ULevelConfig::GetConfigForLevel(UDataTable* DataTable, int32 Level)
{
	TArray<FLevelConfigInfo> Configs = LoadConfigsFromDataTable(DataTable);
	int32 ConfigIndex = FindConfigIndexForLevel(Configs, Level);
	if (ConfigIndex != INDEX_NONE)
	{
		return Configs[ConfigIndex];
	}

	// 返回默认配置
	FLevelConfigInfo DefaultConfig;
	DefaultConfig.CultivationName = TEXT("Unknown");
	DefaultConfig.MinLevel = 1;
	DefaultConfig.MaxLevel = 1;
	DefaultConfig.BaseXP = 100;
	DefaultConfig.XPMultiplier = 1.0f;
	DefaultConfig.AttributePointsPerLevel = 1;
	DefaultConfig.SpellPointsPerLevel = 1;
	return DefaultConfig;
}

bool ULevelConfig::CanLevelUp(UDataTable* DataTable, int32 CurrentLevel, int32 CurrentXP)
{
	int32 XPRequiredForNextLevel = GetXPRequiredForCurrentLevel(DataTable, CurrentLevel);
	return CurrentXP >= XPRequiredForNextLevel;
}

int32 ULevelConfig::GetXPRequiredForNextLevel(UDataTable* DataTable, int32 CurrentLevel, int32 CurrentXP)
{
	int32 XPRequiredForNextLevel = GetXPRequiredForCurrentLevel(DataTable, CurrentLevel);
	return FMath::Max(0, XPRequiredForNextLevel - CurrentXP);
}

int32 ULevelConfig::FindConfigIndexForLevel(const TArray<FLevelConfigInfo>& Configs, int32 Level)
{
	for (int32 i = 0; i < Configs.Num(); ++i)
	{
		const FLevelConfigInfo& Config = Configs[i];
		if (Level >= Config.MinLevel && Level <= Config.MaxLevel)
		{
			return i;
		}
	}
	return INDEX_NONE;
}

int32 ULevelConfig::GetMaxLingQiForLevel(UDataTable* DataTable, int32 Level)
{
	FLevelConfigInfo Config = GetConfigForLevel(DataTable, Level);
	return Config.MaxLingQi;
}

float ULevelConfig::CalculateLingQiPercent(UDataTable* DataTable, int32 CurrentLevel, int32 CurrentLingQi)
{
	int32 MaxLingQi = GetMaxLingQiForLevel(DataTable, CurrentLevel);
	if (MaxLingQi > 0)
	{
		return FMath::Clamp(static_cast<float>(CurrentLingQi) / static_cast<float>(MaxLingQi), 0.0f, 1.0f);
	}
	return 0.0f;
}

int32 ULevelConfig::FindLevelForLevelAndXP(UDataTable* DataTable, int32 CurrentLevel, int32 CurrentXP)
{
	if (!DataTable)
	{
		return CurrentLevel;
	}

	TArray<FLevelConfigInfo> Configs = LoadConfigsFromDataTable(DataTable);
	if (Configs.Num() == 0)
	{
		return CurrentLevel;
	}

	int32 NewLevel = CurrentLevel;
	int32 RemainingXP = CurrentXP;

	// 循环检查是否可以升级
	while (RemainingXP > 0)
	{
		// 获取当前等级升级所需的经验值
		int32 XPRequiredForCurrentLevel = GetXPRequiredForCurrentLevel(DataTable, NewLevel);
		
		if (RemainingXP >= XPRequiredForCurrentLevel)
		{
			// 可以升级
			RemainingXP -= XPRequiredForCurrentLevel;
			NewLevel++;
			
			// 检查是否已达到当前修炼阶段的最高等级
			int32 ConfigIndex = FindConfigIndexForLevel(Configs, NewLevel);
			if (ConfigIndex == INDEX_NONE)
			{
				// 没有找到配置，可能需要进入下一个修炼阶段
				ConfigIndex = FindConfigIndexForLevel(Configs, NewLevel - 1);
				if (ConfigIndex != INDEX_NONE && ConfigIndex + 1 < Configs.Num())
				{
					// 进入下一个修炼阶段
					NewLevel = Configs[ConfigIndex + 1].MinLevel;
				}
				else
				{
					// 已达到最高等级，回退一级
					NewLevel--;
					break;
				}
			}
		}
		else
		{
			// 经验不足，无法升级
			break;
		}
	}

	return NewLevel;
}

int32 ULevelConfig::GetAttributePointsForLevel(UDataTable* DataTable, int32 Level)
{
	FLevelConfigInfo Config = GetConfigForLevel(DataTable, Level);
	return Config.AttributePointsPerLevel;
}

int32 ULevelConfig::GetSpellPointsForLevel(UDataTable* DataTable, int32 Level)
{
	FLevelConfigInfo Config = GetConfigForLevel(DataTable, Level);
	return Config.SpellPointsPerLevel;
}

int32 ULevelConfig::GetXPRequiredForCurrentLevel(UDataTable* DataTable, int32 Level)
{
	TArray<FLevelConfigInfo> Configs = LoadConfigsFromDataTable(DataTable);
	int32 ConfigIndex = FindConfigIndexForLevel(Configs, Level);
	if (ConfigIndex == INDEX_NONE)
	{
		UE_LOG(LogTemp, Warning, TEXT("ULevelConfig::GetXPRequiredForCurrentLevel - No config found for level %d"), Level);
		return 0;
	}

	const FLevelConfigInfo& Config = Configs[ConfigIndex];
	
	// 计算当前等级在当前境界内的位置
	int32 LevelInCurrentConfig = Level - Config.MinLevel + 1;
	
	// 计算当前等级升级所需的经验值
	int32 XPForThisLevel = FMath::RoundToInt(Config.BaseXP * FMath::Pow(Config.XPMultiplier, LevelInCurrentConfig - 1));
	
	return XPForThisLevel;
}